home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / cpp112.zoo / src / input.c < prev    next >
C/C++ Source or Header  |  1994-07-06  |  4KB  |  184 lines

  1.  
  2. /*---------------------------------------------------------------------*\
  3. |                                    |
  4. | CPP -- a stand-alone C preprocessor                    |
  5. | Copyright (c) 1993 Hacker Ltd.        Author: Scott Bigham    |
  6. |                                    |
  7. | Permission is granted to anyone to use this software for any purpose    |
  8. | on any computer system, and to redistribute it freely, with the    |
  9. | following restrictions:                        |
  10. | - No charge may be made other than reasonable charges for repro-    |
  11. |     duction.                                |
  12. | - Modified versions must be clearly marked as such.            |
  13. | - The author is not responsible for any harmful consequences of    |
  14. |     using this software, even if they result from defects therein.    |
  15. |                                    |
  16. | input.c -- line-level input routines                    |
  17. \*---------------------------------------------------------------------*/
  18.  
  19. #include <stdlib.h>
  20. #include <stddef.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "global.h"
  24.  
  25. #define LINEBUF 128
  26.  
  27. char *cur_file;
  28. unsigned long last_line,    /* the last line we registered */
  29.   this_line,            /* the line we just read */
  30.   next_line;            /* the line we're about to read */
  31.  
  32. static char *the_line;
  33. static size_t the_size;
  34. char *next_c;
  35.  
  36. /*
  37.    trigraph() -- translate trigraph sequences in string |s|.  |s| is modified
  38.    in place.
  39. */
  40. static void trigraph(s)
  41.   register char *s;
  42. {
  43.   register char *t = s;
  44.  
  45.   while (*s) {
  46.     if (*s == '?' && s[1] == '?')
  47.       switch (s[2]) {
  48.       case '=':
  49.     *t++ = '#';
  50.     goto skip;
  51.       case '/':
  52.     *t++ = '\\';
  53.     goto skip;
  54.       case '\'':
  55.     *t++ = '^';
  56.     goto skip;
  57.       case '(':
  58.     *t++ = '[';
  59.     goto skip;
  60.       case ')':
  61.     *t++ = ']';
  62.     goto skip;
  63.       case '!':
  64.     *t++ = '|';
  65.     goto skip;
  66.       case '<':
  67.     *t++ = '{';
  68.     goto skip;
  69.       case '>':
  70.     *t++ = '}';
  71.     goto skip;
  72.       case '-':
  73.     *t++ = '~';
  74.       skip:s += 3;
  75.     break;
  76.       default:
  77.     *t++ = *s++;
  78.     } else
  79.       *t++ = *s++;
  80.   }
  81.   *t = '\0';
  82. }
  83.  
  84. /*
  85.    getline() -- read a line from the global input file |inf|, translate
  86.    trigraphs if necessary, collapse lines spliced with \<newline>, and strip
  87.    comments if necessary
  88. */
  89. char *getline()
  90. {
  91.   register char *s, *t;
  92.   ptrdiff_t dp;
  93.  
  94.   this_line = next_line;    /* tomorrow never arrives; it just becomes
  95.                    today */
  96.   if (!the_line)
  97.     the_line = mallok(the_size = LINEBUF);
  98.   s = the_line;
  99.   if (!fgets(s, the_size, inf)) {
  100.     return NULL;
  101.   }
  102.   if (do_trigraphs)
  103.     trigraph(s);
  104.   t = s + strlen(s);
  105.   next_line++;
  106.   for (;;) {
  107.     if (t[-1] != '\n' || (--t > s && t[-1] == '\\')) {
  108.       if (t[-1] == '\\') {
  109.     t--;
  110.     next_line++;
  111.       }
  112.       if (the_size - (t - s) < LINEBUF) {
  113.     dp = t - s;
  114.     the_size += LINEBUF;
  115.     s = reallok(s, the_size);
  116.     t = s + dp;
  117.       }
  118.       if (!fgets(t, (int)(the_size - (t - s)), inf)) {
  119.     *t = '\0';
  120.     break;
  121.       }
  122.       if (do_trigraphs)
  123.     trigraph(t);
  124.       t += strlen(t);
  125.     } else
  126.       break;
  127.   }
  128.   *t++ = '\0';
  129.   the_line = next_c = s;
  130.   return s;
  131. }
  132.  
  133. /*
  134.    flush_line() -- discard the rest of the input line and any pushed-back
  135.    tokens
  136. */
  137. void flush_line()
  138. {
  139.   next_c = NULL;
  140.   flush_tokenizer();
  141. }
  142.  
  143. /*
  144.    rest_of_line() -- return a pointer to the remainder of the input line
  145. */
  146. char *rest_of_line()
  147. {
  148.   return next_c;
  149. }
  150.  
  151. /*
  152.    tokenize_string() -- convert the string pointed to by |s| into a list of
  153.    tokens.  If |s| is NULL, convert the remainder of the input line.
  154. */
  155. TokenP tokenize_string(s)
  156.   char *s;
  157. {
  158.   char *old_next_c;
  159.   register TokenP T = NULL, t = NULL, tt;
  160.  
  161.   if (s) {
  162.     old_next_c = next_c;
  163.     next_c = s;
  164.   }
  165.   for (;;) {
  166.     tt = _one_token();
  167.     if (tt->type == EOL) {
  168.       free_token(tt);
  169.       break;
  170.     }
  171.     if (!T)
  172.       t = T = tt;
  173.     else
  174.       t = t->next = tt;
  175.   }
  176.   if (s)
  177.     next_c = old_next_c;
  178.   if (t) {
  179.     t->next = NULL;
  180.     clear_ws(T);
  181.   }
  182.   return T;
  183. }
  184.